package de.java.swing.extension.ui;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;

import javax.swing.JPanel;

import de.java.swing.extension.utils.ExtendedPanelConstants;

/**
 * TODO Kommentar.
 * 
 * @author Patrick Haas
 * @since 1.0.0
 * 
 * 
 */
public class ExtendedPanel extends JPanel implements ExtendedPanelConstants {

	private static final long serialVersionUID = -3872195529584342647L;

	private int backGroundImageAlignment = BACKGROUND_IMAGE_ALIGNMENT_NORMAL;

	private ExtendedImage backgroundImage;

	private float opacity;

	public ExtendedPanel() {
		this(BACKGROUND_IMAGE_ALIGNMENT_NORMAL);
	}

	public ExtendedPanel(int backgroundImageAlignment) {
		this(backgroundImageAlignment, 0.0f);
	}

	public ExtendedPanel(float opacity) {
		this(BACKGROUND_IMAGE_ALIGNMENT_NORMAL, opacity);
	}

	public ExtendedPanel(int backgroundImageAlignment, float opacity) {
		this.opacity = opacity;
		this.backGroundImageAlignment = backgroundImageAlignment;
		this.setBackground(new Color(0, 0, 0, 0));
		this.setOpaque(false);
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);

		final Graphics2D g2d = (Graphics2D) g;

		final Composite oldComp = g2d.getComposite();

		final Composite alphaComp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, this.opacity);

		g2d.setComposite(alphaComp);

		if (isBackgroundSet()) {
			g2d.setColor(this.getBackground());
			g2d.fillRect(0, 0, this.getSize().width, this.getSize().height);
		}

		if (backgroundImage != null) {
			Point p = new Point();
			Dimension d = new Dimension(backgroundImage.getImage().getWidth(this), backgroundImage.getImage().getHeight(this));

			switch (backGroundImageAlignment) {
			case BACKGROUND_IMAGE_ALIGNMENT_NORMAL:
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_HORIZONTAL_STRETCHED:
				d.width = this.getSize().width;
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_VERTICAL_STRETCHED:
				d.height = this.getSize().height;
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_BOTH_STRETCHED:
				d = this.getPreferredSize();
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_TOP_CENTER:
				p.x = this.getSize().width / 2 - backgroundImage.getImage().getWidth(this) / 2;
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_TOP_RIGHT:
				p.x = this.getSize().width - backgroundImage.getImage().getWidth(this);
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_CENTER:
				p.x = this.getSize().width / 2 - backgroundImage.getImage().getWidth(this) / 2;
				p.y = this.getSize().height / 2 - backgroundImage.getImage().getHeight(this) / 2;
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_LEFT:
				p.y = this.getSize().height / 2 - backgroundImage.getImage().getHeight(this) / 2;
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_RIGHT:
				p.x = this.getSize().width - backgroundImage.getImage().getWidth(this);
				p.y = this.getSize().height / 2 - backgroundImage.getImage().getHeight(this) / 2;
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_BOTTOM_CENTER:
				p.x = this.getSize().width / 2 - backgroundImage.getImage().getWidth(this) / 2;
				p.y = this.getSize().height - backgroundImage.getImage().getHeight(this);
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_BOTTOM_LEFT:
				p.y = this.getSize().height - backgroundImage.getImage().getHeight(this);
				break;
			case BACKGROUND_IMAGE_ALIGNMENT_BOTTOM_RIGHT:
				p.x = this.getSize().width - backgroundImage.getImage().getWidth(this);
				p.y = this.getSize().height - backgroundImage.getImage().getHeight(this);
				break;
			}

			if (d.width == 0)
				d.width = this.getSize().width;

			if (d.height == 0)
				d.height = this.getSize().height;

			g2d.drawImage(backgroundImage.getImage(), p.x, p.y, d.width, d.height, this);
		}

		g2d.setComposite(oldComp);

	}

	/**
	 * Getter: backgroundImage.
	 * 
	 * @return {@link Image}
	 */
	public ExtendedImage getBackgroundImage() {
		return backgroundImage;
	}

	/**
	 * Setter: backgroundImage.
	 * 
	 * @param backgroundImage
	 *            Hintergrundbild als {@link Image}
	 */
	public void setBackgroundImage(ExtendedImage backgroundImage) {
		this.backgroundImage = backgroundImage;
		revalidate();
		repaint();
	}

	/**
	 * @return the backGroundImageAlignment
	 */
	public int getBackGroundImageAlignment() {
		return backGroundImageAlignment;
	}

	/**
	 * @param backGroundImageAlignment
	 *            the backGroundImageAlignment to set
	 */
	public void setBackgroundImageAlignment(int backGroundImageAlignment) {
		this.backGroundImageAlignment = backGroundImageAlignment;
		revalidate();
		repaint();
	}
}
